<?php

namespace App\Http\Controllers\Account;

use Exception;
use App\Models\User;
use App\Models\Audit;
use App\Models\Station\Report;
use App\Models\Station;
use Illuminate\Http\Request;
use App\Models\Inspection\Node;
use App\Jobs\Logic\Account\Signin;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
use App\Repositories\ImageRepository;
use Illuminate\Support\Facades\Storage;
use App\Repositories\InspectionRepository;
use App\Repositories\AttendanceRepository;
use App\Http\Requests\User\Personal\JoinCompany;
use App\Http\Requests\User\Personal\ReportStation;
use App\Http\Requests\User\Personal\ModifyProfile;
use App\Http\Requests\User\Personal\InspectionRequest;
use App\Http\Requests\Account\Attendance\SigninRequest;
use App\Http\Requests\User\Personal\ModifyIdentification;

/**
 * 用户业务逻辑控制器
 *
 * Date: 20/03/2018
 * @author George
 * @package App\Http\Controllers\Account
 */
class PersonalController extends Controller
{
	protected $userRepository;
	protected $attendanceRepository;
	protected $inspectionRepository;

	/**
	 * PersonalController constructor.
	 * @param UserRepository $userRepository
	 * @param AttendanceRepository $attendanceRepository
	 * @param InspectionRepository $inspectionRepository
	 */
	public function __construct(
		UserRepository $userRepository,
		AttendanceRepository $attendanceRepository,
		InspectionRepository $inspectionRepository
	)
	{
		$this->userRepository = $userRepository;
		$this->attendanceRepository = $attendanceRepository;
		$this->inspectionRepository = $inspectionRepository;
	}

	/**
	 * 获取用户信息
	 *
	 * Date: 29/04/2018
	 * @author George
	 * @param Request $request
	 * @return \Illuminate\Http\JsonResponse
	 * @throws \Betterde\Tree\Exceptions\TreeException
	 */
	public function profile(Request $request)
	{
		$user = Auth::user();
		if ($request->userAgent() === 'Browser') {
			$user->getMenus(true);
		}
		$user->getCompany();
		return success($user);
	}

	/**
	 * 获取用户的排班信息
	 *
	 * Date: 17/04/2018
	 * @author George
	 * @param Request $request
	 * @return \Illuminate\Http\JsonResponse
	 * @throws \App\Exceptions\GeneralException
	 */
	public function schedule(Request $request)
	{
		/**
		 * @var User $user
		 */
		$user = $request->user();
		$schedule = $user->getSchedule();
		if ($schedule) {
			$attendance = $user->getAttendance();
			$schedule->offsetSet('checkin', optional($attendance)->checkin_time);
			$schedule->offsetSet('checkout', optional($attendance)->checkout_time);
			return success($schedule);
		}
		return notFound('未找到排班记录');
	}

	/**
	 * 修改头像
	 *
	 * Date: 21/03/2018
	 * @author George
	 * @param Request $request
	 * @return \Illuminate\Http\JsonResponse
	 * @throws \Throwable
	 */
	public function modifyAvatar(Request $request)
	{
		$this->validate($request, [
			'avatar' => 'required|image|mimes:jpeg,png|dimensions:max_width=512,max_height=512'
		], [
			'avatar.required' => '请选择要用作头像的图片',
			'avatar.image' => '只能上传图片格式',
			'avatar.mimes' => '只支持JPG和PNG格式的图片',
			'avatar.dimensions' => '图片宽高不得超过512像素',
		]);

		try {
			$file = $request->file('avatar');
			$path = $file->store('avatar', 'public');
			$url = Storage::url($path);
		} catch (Exception $exception) {
			return internalError();
		}

		$this->userRepository->modifyAvatar($url, $request->user());
		return updated(['avatar' => $url], '头像修改成功');
	}

	/**
	 * 修改密码
	 *
	 * Date: 21/03/2018
	 * @author George
	 * @param Request $request
	 * @return \Illuminate\Http\JsonResponse
	 * @throws \Throwable
	 */
	public function modifyPassword(Request $request)
	{
		$params = $this->validate($request, [
			'old_password' => 'required',
			'new_password' => 'required',
		], [
			'old_password.required' => '请输入旧密码',
			'new_password.required' => '请输入新密码',
		]);

		$result = $this->userRepository->modifyPassword($params['old_password'], $params['new_password'], $request->user());

		if ($result) {
			return updated('您的密码修改成功');
		}

		return failed('您输入的旧密码有误，修改密码失败！');
	}

	/**
	 * 修改用户身份信息
	 *
	 * Date: 11/04/2018
	 * @author George
	 * @param ModifyIdentification $request
	 * @return \Illuminate\Http\JsonResponse
	 * @throws \App\Exceptions\GeneralException
	 */
	public function modifyIdentification(ModifyIdentification $request)
	{
		$personal = $request->only([
			'name',
			'gender',
			'birthday',
			'identification',
		]);

		$identification = $request->only([
			'issuer',
			'indate',
			'nation',
			'hometown',
			'identification',
			'identification_front',
			'identification_reverse'
		]);

		$this->userRepository->updateByPrimary(Auth::id(), $personal);
		$result = $this->userRepository->modifyIdentification($identification);
		return updated($result);
	}

	/**
	 * 补全用户信息
	 *
	 * Date: 27/04/2018
	 * @author George
	 * @param ModifyProfile $request
	 * @return \Illuminate\Http\JsonResponse
	 * @throws \App\Exceptions\GeneralException
	 */
	public function modifyProfile(ModifyProfile $request)
	{
		$attributes = $this->extractInputFromRules($request, $request->rules());
		$user = Auth::user();
		try {
			$result = $user->personal()->create($attributes);
		} catch (Exception $exception) {
			return failed('无法保存你的个人信息，请稍后再试');
		}
		return stored($result);
	}

	/**
	 * 用户打卡
	 *
	 * Date: 17/04/2018
	 * @author George
	 * @param SigninRequest $request
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function signin(SigninRequest $request)
	{
		$attributes = $request->all();
		Signin::dispatch($attributes);
		return accepted();
	}

	/**
	 * 加入公司
	 *
	 * Date: 27/04/2018
	 * @author George
	 * @param JoinCompany $request
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function joinCompany(JoinCompany $request)
	{
		$company_id = $request->get('company_id');
		$attributes = [
			'auditable_id' => Auth::id(),
			'auditable_type' => 'user',
			'proposer' => Auth::id(),
			'company_id' => $company_id
		];
		$audit = Audit::create($attributes);
		return success($audit);
	}

	/**
	 * 创建巡检记录
	 *
	 * Date: 01/05/2018
	 * @author George
	 * @param InspectionRequest $request
	 * @return \Illuminate\Http\JsonResponse
	 * @throws \App\Exceptions\GeneralException
	 */
	public function inspection(InspectionRequest $request)
	{
		$attributes = $this->extractInputFromRules($request, $request->rules());
		array_pull($attributes, 'images');
		$node = Node::with('circle.line')->where('id', $attributes['node_id'])->first();
		$user = Auth::user();

		if (! $node) {
			return failed('巡检节点不存在');
		}

		if (! $node->circle) {
			return failed('巡检节点未关联到圈');
		}

		if (! $node->circle->line) {
			return failed('巡检节点未关联到线路');
		}

		$inspection = $this->inspectionRepository->store($user, $attributes, $request->file('images'), $node);

		return stored($inspection);
	}

	/**
	 * 人员报岗
	 *
	 * Date: 30/04/2018
	 * @author George
	 * @param ReportStation $request
	 * @return \Illuminate\Http\JsonResponse
	 * @throws \App\Exceptions\GeneralException
	 */
	public function station(ReportStation $request)
	{
		$attributes = $this->extractInputFromRules($request, $request->rules());
		array_pull($attributes, 'images');
		$station = Station::with('project')->where('id', $attributes['station_id'])->firstOrFail();
		$user = Auth::user();
		$attributes['company_id'] = $station->company_id;
		$attributes['project_id'] = $station->project_id;
		$attributes['project_name'] = optional($station->project)->name;
		$attributes['user_id'] = $user->id;
		$attributes['user_name'] = $user->name;
		// 创建报岗记录
		$report = Report::create($attributes);
		$images = $request->file('images');
		$imageRepository = new ImageRepository();
		// 存储图片
		$report->images = $imageRepository->store($images, $user->id, $station->company_id, $station->project_id, $report);
		return stored($report);
	}
}
